/*-------------------------------------------------------------------------
FileName     : HEpoll.h
Description  : 封装高性能epoll的操作
remark       : ET-mode
Modification :
--------------------------------------------------------------------------
   1、Date  2020-08-20       create     hejl 
-------------------------------------------------------------------------*/
#ifndef _HEPOLL_H_
#define _HEPOLL_H_
#include <cstddef>
#include <thread>
#include <string>
#include <map>
#include "ConnectMeta.h"
#include "AliasRef.h" // 别名引用

//#include <mutex> // std::mutex, std::unique_lock
//#include <condition_variable> // std::condition_variable



using namespace std;


class HEpoll
{
public:
    HEpoll( void );
    ~HEpoll( void );
    int init( void );
    int run( bool runInNewThread );
    void notifyExit( void );
    void unInit( void );

    string toString();
    
public:
    ConnectMetaSPtr addTcpListen(int port);

    ConnectMetaSPtr addTcpConnect(const string& dstHost, int port, int timeoutSec, bool noblock);
    ConnectMetaSPtr addTcpConnect2(const string& dstHost, int port, int timeoutSec, function<void(bool,ConnectMetaSPtr)> connectResultCB);

    int addTimer(int sec, bool once, function<void(int timerFd)> callBack);
    void delTimer(int timerFd);

    void setAliasNameInstance(shared_ptr<AliasRef<ConnectMetaSPtr>> ptr);
    bool addAliasName(const string& aliasName, ConnectMetaSPtr connMeta);
    void delAliasName(const string& aliasName);
    ConnectMetaSPtr find(int fd);
    ConnectMetaSPtr find(const string& aliasName);

private: // CallBack
    void FuncOnAccept(int cliFd, ConnectMetaSPtr);
    void FuncOnClose(int fd, const string& errMsg);
    void FuncOnRemoveRef(int fd, ConnectMetaSPtr connMeta);
    void FuncOnTimer(int timeFd, bool once, function<void(int timerFd)> callBack);
    
protected:
    int _run( void );
    ConnectMetaSPtr addInitConnMeta(int sockFd, FdState fdState);


private:
    int epfd; // epoll socket
    std::thread thread;
    bool newThread;
    bool exit;

    std::mutex mapMtx;
    map<int, ConnectMetaSPtr> connMetaMap;

    shared_ptr<AliasRef<ConnectMetaSPtr>> aliasNameRef;
};


#endif